<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Game Room</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.0/sockjs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        .container {
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            width: 500px;
            text-align: center;
        }
        h2 {
            margin-bottom: 20px;
        }
        .input-section {
            margin-bottom: 20px;
            text-align: left;
        }
        .input-group {
            margin-bottom: 15px;
        }
        .input-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        .input-group input {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        .start-game-button {
            width: 100%;
            padding: 15px;
            background-color: #28a745;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            margin-top: 20px;
        }
        .start-game-button:hover {
            background-color: #1e7e34;
        }
        .start-game-button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }
        .current-room {
            margin-top: 20px;
            padding: 10px;
            background-color: #e9ecef;
            border-radius: 5px;
        }
        .grid {
            display: grid;
            grid-template-columns: repeat(50, 10px);
            grid-template-rows: repeat(50, 10px);
            margin-top: 20px;
        }
        .grid .cell {
            width: 10px;
            height: 10px;
            border: 1px solid #ddd;
            position: relative;
            cursor: pointer;
            transition: background-color 0.2s ease;
        }
        .grid .cell:hover {
            background-color: #f0f0f0;
        }
        .grid:focus {
            outline: 2px solid #007bff;
            outline-offset: 2px;
        }
        .grid .player {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            position: absolute;
            top: 5px;
            left: 5px;
            border: 2px solid #fff;
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
            cursor: pointer;
            transition: transform 0.2s ease;
        }
        .grid .player:hover {
            transform: scale(1.1);
        }
        .player-list {
            margin-top: 20px;
            list-style: none;
            padding: 0;
        }
        .player-list li {
            padding: 5px 0;
        }
        .hidden {
            display: none;
        }
        .loading {
            color: #666;
            font-style: italic;
        }
    </style>
</head>
<body>

<div class="container">
    <h2>Welcome to the Game</h2>

    <!-- 输入区域 -->
    <div class="input-section" id="inputSection">
        <div class="input-group">
            <label for="username">用户名:</label>
            <input type="text" id="username" placeholder="请输入用户名" maxlength="20">
        </div>
        <div class="input-group">
            <label for="mbtiSelect">选择你的MBTI人格类型:</label>
            <select id="mbtiSelect" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;">
                <option value="">请选择你的MBTI类型</option>
                <!-- MBTI选项将通过JavaScript动态加载 -->
            </select>
        </div>
        <button class="start-game-button" onclick="startGame()">开始游戏</button>
    </div>

    <!-- 当前房间显示区域 -->
    <div class="current-room hidden" id="currentRoom">
        <button onclick="showInputSection()" style="float: right; padding: 5px 10px; background-color: #dc3545; color: white; border: none; border-radius: 3px; cursor: pointer;">返回</button>
    </div>

    <!-- 控制说明 -->
    <div class="control-info hidden" id="controlInfo" style="margin-top: 10px; padding: 10px; background-color: #f8f9fa; border-radius: 5px; font-size: 14px; color: #666;">
        <strong>控制说明：</strong><br>
        鼠标点击网格或使用键盘控制移动<br>
        <span style="font-family: monospace;">↑↓←→</span> 或 <span style="font-family: monospace;">WASD</span> 键移动<br>
        <strong>房间限制：</strong> 每个房间最多2人
    </div>

    <!-- 网格游戏区域 -->
    <div class="grid hidden" id="gameGrid"></div>

    <!-- 玩家列表 -->
    <ul class="player-list hidden" id="playerList"></ul>
</div>

<script>

    document.getElementById('username').value = new Date()*1
        document.getElementById('mbtiSelect').value = 'ENFJ'
</script>

<script>

    var socket = new SockJS('/game-websocket');
    var stompClient = Stomp.over(socket);
    var currentRoom = null;
    var currentPlayer = null;
    var playerElements = {};
    var currentSubscription = null;

    // 连接WebSocket
    stompClient.connect({}, function (frame) {
        console.log('Connected: ' + frame);
        
        // 启动心跳
        startHeartbeat();
        
        // 加载MBTI类型选项
        loadMBTITypes();
    });

    // 订阅错误消息
    stompClient.subscribe('/user/queue/error', function (message) {
        var errorMessage = message.body;
        alert('错误: ' + errorMessage);
        showInputSection();
    });

    // 加载MBTI类型
    async function loadMBTITypes() {
        try {
            const response = await fetch('/api/game/mbti/types');
            const result = await response.json();
            
            if (result.code === 200) {
                const mbtiSelect = document.getElementById('mbtiSelect');
                const types = result.data.types;
                
                // 清空现有选项（保留默认选项）
                while (mbtiSelect.options.length > 1) {
                    mbtiSelect.remove(1);
                }
                
                // 添加MBTI类型选项
                Object.values(types).forEach(type => {
                    const option = document.createElement('option');
                    option.value = type.type;
                    option.textContent = `${type.type} - ${type.displayName}`;
                    option.title = type.description;
                    mbtiSelect.appendChild(option);
                });
                mbtiSelect.value = 'ENFJ'
            }
        } catch (error) {
            console.error('加载MBTI类型失败:', error);
        }
    }

    // 开始游戏
    async function startGame() {
        const username = document.getElementById('username').value.trim();
        const mbtiType = document.getElementById('mbtiSelect').value;

        if (!username) {
            alert('请输入用户名');
            return;
        }

        if (!mbtiType) {
            alert('请选择你的MBTI人格类型');
            return;
        }


        // 显示加载状态
        const startButton = document.querySelector('.start-game-button');
        startButton.textContent = '正在加入游戏...';
        startButton.disabled = true;

        try {
            // 通过HTTP请求加入房间
            const response = await fetch('/api/game/join', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer ' + 'eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoi55So5oi3XzE3NTUxNjc3NjMyMjEiLCJpZCI6NjYsInN1YiI6IjI2MDE4MDM3NTRAcXEuY29tIiwiaWF0IjoxNzU1MTY3NzYzLCJleHAiOjE3NjM4MDc3NjN9.n_L6e7FY8My0rZHlFLrh72fn05uoao3uJYj1Ms0kZH0'
                },
                body: JSON.stringify({
                    username: username,
                    status: 'online',
                    position: { x: 0, y: 0 },
                    mbtiType: mbtiType
                })
            });

            const result = await response.json();

            if (result.data.success) {
                // 加入成功，进入游戏
                currentPlayer = {
                    id: username, // 使用用户名作为ID
                    username: username,
                    status: 'online',
                    position: { x: 0, y: 0 },
                    roomId: result.data.roomId,
                    mbtiType: mbtiType
                };
                currentRoom = result.data.roomId;

                enterGame(result.data.roomId);
            } else {
                alert('加入失败: ' + result.data.message);
                startButton.textContent = '开始游戏';
                startButton.disabled = false;
            }
        } catch (error) {
            console.error('加入游戏失败:', error);
            alert('加入游戏失败，请重试');
            startButton.textContent = '开始游戏';
            startButton.disabled = false;
        }
    }

    // 进入游戏
    function enterGame(roomId) {
        // 从房间ID中提取MBTI广场信息
        const mbtiSquare = roomId.split('_')[0];
        document.getElementById("currentRoom").innerHTML =
            `<span>当前房间: ${roomId} (${mbtiSquare}广场)</span><button onclick="showInputSection()" style="float: right; padding: 5px 10px; background-color: #dc3545; color: white; border: none; border-radius: 3px; cursor: pointer;">返回</button>`;

        document.getElementById('inputSection').classList.add('hidden');
        document.getElementById('currentRoom').classList.remove('hidden');
        document.getElementById('gameGrid').classList.remove('hidden');
        document.getElementById('playerList').classList.remove('hidden');
        document.getElementById('controlInfo').classList.remove('hidden');

        document.getElementById("playerList").innerHTML = '';
        document.querySelectorAll('.player').forEach(function(playerElement) {
            playerElement.remove();
        });
        renderGrid();

        // 订阅当前房间的消息
        if (currentSubscription) {
            currentSubscription.unsubscribe();
        }
        currentSubscription = stompClient.subscribe('/topic/room/' + roomId, function (message) {
            var players = JSON.parse(message.body);
            console.log('收到房间 ' + roomId + ' 的玩家列表更新:', players);
            updatePlayerList(players);
            try {
                const me = players.find(p => String(p.id) === String(currentPlayer.id));
                if (me && me.position) {
                    currentPlayer.position = { x: me.position.x, y: me.position.y };
                }
            } catch (e) {}
        });

        stompClient.send("/app/joinGame", {}, JSON.stringify(currentPlayer));

        // 立即拉一次房间数据，首次进入无需点击即可渲染
        fetch('/api/game/room/' + roomId)
            .then(r => r.json())
            .then(res => {
                if (res && (res.code === '200' || res.code === 200)) {
                    const players = res.data && res.data.players ? res.data.players : [];
                    updatePlayerList(players);
                    try {
                        const me = players.find(p => String(p.id) === String(currentPlayer.id));
                        if (me && me.position) {
                            currentPlayer.position = { x: me.position.x, y: me.position.y };
                        }
                    } catch (e) {}
                }
            })
            .catch(() => {});
    }

    // 显示输入区域
    function showInputSection() {
        // 如果当前在房间中，先离开房间
        if (currentPlayer && currentRoom) {
            console.log('发送离开消息:', currentPlayer);
            stompClient.send("/app/leaveGame", {}, JSON.stringify(currentPlayer));
        }

        document.getElementById('inputSection').classList.remove('hidden');
        document.getElementById('currentRoom').classList.add('hidden');
        document.getElementById('gameGrid').classList.add('hidden');
        document.getElementById('playerList').classList.add('hidden');
        document.getElementById('controlInfo').classList.add('hidden');

        const startButton = document.querySelector('.start-game-button');
        startButton.textContent = '开始游戏';
        startButton.disabled = false;

        document.getElementById('username').value = '';
        document.getElementById('mbtiSelect').value = '';

        currentRoom = null;
        currentPlayer = null;
        playerElements = {};

        if (currentSubscription) {
            currentSubscription.unsubscribe();
            currentSubscription = null;
        }
    }

    // 渲染网格
    function renderGrid() {
        const gameGrid = document.getElementById("gameGrid");
        gameGrid.innerHTML = '';
        for (let row = 0; row < 50; row++) {
            for (let col = 0; col < 50; col++) {
                const cell = document.createElement("div");
                cell.classList.add("cell");
                cell.setAttribute("data-x", col);
                cell.setAttribute("data-y", row);
                cell.addEventListener("click", function () {
                    movePlayerTo(row, col);
                    gameGrid.focus();
                });
                gameGrid.appendChild(cell);
            }
        }

        //wasd移动
        const inputs = {
            w:false,
            a:false,
            s:false,
            d:false
        }

        window.onkeyup = function(e) {
            switch (e.key) {
                case "w":
                    inputs.w = false;
                    break;
                case "a":
                    inputs.a = false;
                    break;
                case "s":
                    inputs.s = false;
                    break;
                case "d":
                    inputs.d = false;
                    break;
            }

        }

        window.onkeydown = function(e) {
            switch (e.key) {
                case "w":
                    inputs.w = true;
                    break;
                case "a":
                    inputs.a = true;
                    break;
                case "s":
                    inputs.s = true;
                    break;
                case "d":
                    inputs.d = true;
                    break;
            }
        }

        const update = ()=>{
            if(inputs.w){
                movePlayerTo(currentPlayer.position.y-1, currentPlayer.position.x);
            }
            if(inputs.a){
                movePlayerTo(currentPlayer.position.y, currentPlayer.position.x-1);
            }
            if(inputs.s){
                movePlayerTo(currentPlayer.position.y+1, currentPlayer.position.x);
            }
            if(inputs.d){
                movePlayerTo(currentPlayer.position.y, currentPlayer.position.x+1);
            }
        }

        setInterval(()=>{
            update()
        }, 1000/60)

        gameGrid.setAttribute("tabindex", "0");
        gameGrid.focus();
    }

    // 更新玩家列表
    function updatePlayerList(players) {
        var playerList = document.getElementById("playerList");
        playerList.innerHTML = '';

        document.querySelectorAll('.player').forEach(function(playerElement) {
            playerElement.remove();
        });

        var currentPlayerIds = players.map(p => String(p.id));
        Object.keys(playerElements).forEach(function(playerId) {
            if (!currentPlayerIds.includes(playerId)) {
                delete playerElements[playerId];
            }
        });

        players.forEach(function (player) {
            if (!player.position) {
                console.warn(`Player ${player.username || player.id} has no position, setting default`);
                player.position = { x: 0, y: 0 };
            }

            var listItem = document.createElement("li");
            var playerColor = getPlayerColor(player.id);
            var colorIndicator = document.createElement("span");
            colorIndicator.style.display = "inline-block";
            colorIndicator.style.width = "12px";
            colorIndicator.style.height = "12px";
            colorIndicator.style.borderRadius = "50%";
            colorIndicator.style.backgroundColor = playerColor;
            colorIndicator.style.marginRight = "8px";
            colorIndicator.style.verticalAlign = "middle";

            listItem.appendChild(colorIndicator);
            listItem.appendChild(document.createTextNode(`${player.username} (状态: ${player.status}, 位置: (${player.position.x}, ${player.position.y}))`));

            if (currentPlayer && String(player.id) === String(currentPlayer.id)) {
                listItem.style.fontWeight = "bold";
                listItem.style.color = "#007bff";
            }

            playerList.appendChild(listItem);
            updatePlayerPositionInGrid(player);
        });

        console.log(`更新玩家列表，当前房间玩家数量: ${players.length}`);
    }

    // 移动玩家
    function movePlayerTo(row, col) {
        currentPlayer.position = { x: col, y: row };
        updatePlayerPositionInGrid(currentPlayer);
        stompClient.send("/app/updatePlayer", {}, JSON.stringify(currentPlayer));
    }

    // 更新玩家位置
    function updatePlayerPositionInGrid(player) {
        if (!player || !player.id) {
            console.warn('Invalid player data:', player);
            return;
        }

        if (!player.position) {
            console.warn(`Player ${player.username || player.id} has no position, setting default`);
            player.position = { x: 0, y: 0 };
        }

        const playerId = String(player.id);
        let playerElement = playerElements[playerId];

        if (!playerElement) {
            playerElement = document.createElement("div");
            playerElement.classList.add("player");
            playerElement.setAttribute("data-id", playerId);
            playerElement.setAttribute("data-username", player.username);

            const playerColor = getPlayerColor(playerId);
            playerElement.style.backgroundColor = playerColor;
            playerElement.title = player.username;

            if (currentPlayer && String(playerId) === String(currentPlayer.id)) {
                playerElement.style.border = "3px solid #000";
                playerElement.style.boxShadow = "0 0 10px rgba(0,0,0,0.5)";
            }

            playerElements[playerId] = playerElement;
        }

        const cell = document.querySelector(`.cell[data-x="${player.position.x}"][data-y="${player.position.y}"]`);
        if (cell) {
            const existingPlayer = cell.querySelector('.player');
            if (existingPlayer && existingPlayer.getAttribute('data-id') !== String(playerId)) {
                existingPlayer.remove();
            }
            cell.appendChild(playerElement);
        } else {
            console.warn(`Cell not found for position (${player.position.x}, ${player.position.y})`);
        }
    }
    // 生成玩家颜色
    function getPlayerColor(playerId) {
        const colors = [
            '#007bff', '#28a745', '#dc3545', '#ffc107', '#6f42c1',
            '#fd7e14', '#20c997', '#e83e8c', '#6c757d', '#17a2b8',
            '#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57',
            '#ff9ff3', '#54a0ff', '#5f27cd', '#00d2d3', '#ff9f43'
        ];

        // 确保playerId是字符串类型
        const playerIdStr = String(playerId || '');
        const colorIndex = Math.abs(hashCode(playerIdStr)) % colors.length;
        return colors[colorIndex];
    }

    // 独立的hashCode函数
    function hashCode(str) {
        let hash = 0;
        if (str.length === 0) return hash;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash;
        }
        return hash;
    }
    // 键盘事件处理
    document.addEventListener('keydown', function(event) {
        if (!currentPlayer || !currentRoom) {
            return;
        }

        // 检查是否在输入框中，若是则忽略键盘事件
        if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
            return;
        }

        const currentX = currentPlayer.position.x;
        const currentY = currentPlayer.position.y;
        let newX = currentX;
        let newY = currentY;

        switch(event.key) {
            case 'ArrowUp':
            case 'w':
            case 'W':
                newY = Math.max(0, currentY - 1);
                break;
            case 'ArrowDown':
            case 's':
            case 'S':
                newY = Math.min(9, currentY + 1);
                break;
            case 'ArrowLeft':
            case 'a':
            case 'A':
                newX = Math.max(0, currentX - 1);
                break;
            case 'ArrowRight':
            case 'd':
            case 'D':
                newX = Math.min(9, currentX + 1);
                break;
            default:
                return;
        }

        if (newX !== currentX || newY !== currentY) {
            movePlayerTo(newY, newX);
            event.preventDefault();
        }
    });

    // 心跳机制
    function startHeartbeat() {
        setInterval(function() {
            if (currentPlayer && stompClient.connected) {
                stompClient.send("/app/heartbeat", {}, JSON.stringify(currentPlayer));
            }
        }, 20000); // 每20s发送一次心跳
    }

    // 页面关闭或刷新时发送离开消息
    window.addEventListener('beforeunload', function() {
        console.log("页面已关闭或刷新")
        if (currentPlayer && stompClient.connected) {
            stompClient.send("/app/leaveGame", {}, JSON.stringify(currentPlayer));
        }
    });

    // 网络状态监听
    window.addEventListener('online', function() {
        console.log('网络已连接');
    });

    window.addEventListener('offline', function() {
        console.log('网络已断开');
        if (currentPlayer) {
            alert('网络连接已断开，请检查网络后刷新页面');
        }
    });
</script>

</body>
</html>
